package com.zx.validation.aop;

import com.zx.core.exception.ParameterException;
import com.zx.validation.annotation.ParameterValidation;
import com.zx.validation.annotation.ParameterValidations;
import com.zx.validation.enums.DateTimeFormatEnum;
import com.zx.validation.enums.ValidateRulesEnum;
import com.zx.validation.groups.Create;
import com.zx.validation.groups.Query;
import com.zx.validation.groups.StatusUpdate;
import com.zx.validation.groups.Update;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 方法参数验证切面
 *
 * @author zhou xun
 */
@Aspect
@Component
@Slf4j
public class MethodParameterAspect {

    /**
     * 定义切入点：匹配带有 @ParameterValidations 注解的方法。
     */
    @Pointcut("@annotation(com.zx.validation.annotation.ParameterValidations)")
    public void pointcut() {
    }

    /**
     * 在方法执行前进行参数验证。
     *
     * @param joinPoint JoinPoint 对象，包含了被拦截方法的信息
     * @throws NoSuchMethodException 如果找不到带有指定注解的方法
     * @throws ParameterException    如果参数验证失败
     */
    @Before("pointcut()")
    public void logBefore(JoinPoint joinPoint) throws NoSuchMethodException, ParameterException {
        // 获取方法上的注解
        Method method = Arrays.stream(joinPoint.getSignature().getDeclaringType().getMethods())
                .filter(m -> m.isAnnotationPresent(ParameterValidations.class))
                .filter(m -> m.getName().equals(joinPoint.getSignature().getName()))
                .findFirst()
                .orElseThrow(() -> new NoSuchMethodException("No matching method found with ParameterValidations"));

        ParameterValidations validations = method.getAnnotation(ParameterValidations.class);

        // 获取方法参数列表
        Object[] params = joinPoint.getArgs();
        if (null == validations) {
            throw new ParameterException("参数验证失败!");
        }

        //支持验证参数对象
        if (null != validations && validations.value().length == 1 && params.length == 1) {
            ParameterValidation paramValidation = validations.value()[0];
            //如果规则只有一个,且验证规则是OBJECT
            if (null != paramValidation && paramValidation.rules().length == 1 && paramValidation.rules()[0] == ValidateRulesEnum.OBJECT) {
                Object paramValue = params[0];
                if (null == paramValue) {
                    throw new ParameterException("参数对象不能为空!");
                }
                // 获取paramValue注解了 ParameterValidation注解的属性,并进行参数验证
                validateObjectProperties(paramValidation, paramValue);
                return;
            }

        }

        for (ParameterValidation paramValidation : validations.value()) {
            if (null != paramValidation && (paramValidation.index() < 0 || paramValidation.index() >= params.length)) {
                throw new ParameterException("参数索引超出范围: " + paramValidation.index());
            }
            Object paramValue = params[paramValidation.index()];
            validateSingleValue(paramValidation, paramValue);
        }
    }

    /**
     * 检查验证分组是否匹配
     *
     * @param validationGroups 注解中指定的分组
     * @param targetGroups     目标分组
     * @return 是否匹配
     */
    private boolean isGroupMatch(Class<?>[] validationGroups, Class<?>[] targetGroups) {
        // 如果注解没有指定分组，则默认在任何分组中都生效
        if (null == validationGroups || validationGroups.length == 0) {
            return true;
        }

        // 如果目标分组为空，则不进行分组匹配
        if (null == targetGroups) {
            return false;
        }

        // 检查是否有匹配的分组
        for (Class<?> targetGroup : targetGroups) {
            for (Class<?> validationGroup : validationGroups) {
                if (validationGroup == targetGroup) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 验证对象的属性
     *
     * @param paramValidation 参数验证注解
     * @param paramValue      参数值
     * @throws ParameterException 参数验证失败
     */
    private void validateObjectProperties(ParameterValidation paramValidation, Object paramValue) throws ParameterException {
        if (null == paramValue) {
            throw new ParameterException("参数对象不能为空!");
        }

        Class<?> clazz = paramValue.getClass();

        // 确定要使用的分组
        Class<?>[] targetGroups = paramValidation.groups();

        // 尝试通过接口方法获取分组字段列表（新方式）
        Set<String> groupFieldNames = getGroupFieldNamesFromInterface(paramValue, targetGroups);

        // 判断使用哪种分组验证方式
        if (shouldUseNewGroupValidation(paramValue, targetGroups)) {
            // 使用新的分组验证方式
            validateObjectPropertiesNewWay(paramValidation, paramValue, groupFieldNames);
        } else {
            // 使用传统的分组验证方式
            validateObjectPropertiesTraditionalWay(paramValidation, paramValue);
        }
    }

    /**
     * 判断是否应该使用新的分组验证方式
     *
     * @param paramValue   参数值
     * @param targetGroups 目标分组
     * @return 是否使用新的分组验证方式
     */
    private boolean shouldUseNewGroupValidation(Object paramValue, Class<?>[] targetGroups) {
        // 如果目标分组为空，则不使用任何分组验证方式
        if (null == targetGroups || targetGroups.length == 0) {
            return false;
        }

        // 检查参数对象是否实现了任何分组接口
        for (Class<?> targetGroup : targetGroups) {
            if (targetGroup.isInstance(paramValue)) {
                // 如果实现了分组接口，使用新的分组验证方式
                return true;
            }
        }

        // 否则使用传统分组验证方式
        return false;
    }

    /**
     * 使用新的分组验证方式验证对象属性
     *
     * @param paramValidation 参数验证注解
     * @param paramValue      参数值
     * @param groupFieldNames 分组字段名列表
     * @throws ParameterException 参数验证失败
     */
    private void validateObjectPropertiesNewWay(ParameterValidation paramValidation, Object paramValue, Set<String> groupFieldNames) throws ParameterException {
        Class<?> clazz = paramValue.getClass();
        Class<?>[] targetGroups = paramValidation.groups();

        // 获取类中存在的所有字段名
        Field[] declaredFields = clazz.getDeclaredFields();
        Set<String> actualFieldNames = Arrays.stream(declaredFields)
                .map(Field::getName)
                .collect(Collectors.toSet());

        // 验证分组中指定的字段是否都存在
        if (null != groupFieldNames && !groupFieldNames.isEmpty()) {
            for (String fieldName : groupFieldNames) {
                if (!actualFieldNames.contains(fieldName)) {
                    throw new ParameterException("分组验证中指定的字段 " + fieldName + " 在类 " + clazz.getSimpleName() + " 中不存在");
                }
            }
        }

        // 检查是否有字段属于指定的分组
        boolean hasMatchingFields = false;
        if (groupFieldNames != null && !groupFieldNames.isEmpty()) {
            // 检查是否有字段在分组字段列表中
            for (Field field : clazz.getDeclaredFields()) {
                if (groupFieldNames.contains(field.getName())) {
                    hasMatchingFields = true;
                    break;
                }
            }
        } else if (groupFieldNames != null && groupFieldNames.isEmpty()) {
            // 如果分组字段列表为空，表示该分组没有需要验证的字段
            hasMatchingFields = false;
        }

        // 如果没有任何字段属于指定的分组，则抛出异常（与传统方式保持一致）
        if (!hasMatchingFields && targetGroups != null && targetGroups.length > 0) {
            String errorMessage = "对象中没有字段属于指定的分组: " + Arrays.toString(targetGroups);
            throw new ParameterException(errorMessage);
        }

        // 如果分组字段列表为空，表示该分组没有需要验证的字段，直接返回
        if (groupFieldNames != null && groupFieldNames.isEmpty()) {
            return;
        }

        // 验证字段
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            ParameterValidation fieldParamValidation = field.getAnnotation(ParameterValidation.class);
            if (null != fieldParamValidation) {
                // 如果当前字段在分组字段列表中，则需要验证
                if (groupFieldNames != null && groupFieldNames.contains(field.getName())) {
                    try {
                        Object fieldValue = field.get(paramValue);

                        if (null != fieldParamValidation && fieldParamValidation.rules().length == 1 && fieldParamValidation.rules()[0] == ValidateRulesEnum.OBJECT) {
                            validateObjectProperties(fieldParamValidation, fieldValue);
                        } else if (null != fieldParamValidation && Arrays.stream(fieldParamValidation.rules()).allMatch(rule -> rule == ValidateRulesEnum.OBJECT)) {
                            throw new ParameterException("参数对象验证规则设置错误!");
                        } else {
                            validateSingleValue(fieldParamValidation, fieldValue);
                        }
                    } catch (IllegalAccessException e) {
                        throw new ParameterException("无法访问字段：" + field.getName() + e.getMessage());
                    }
                }
            }
        }
    }

    /**
     * 使用传统的分组验证方式验证对象属性
     *
     * @param paramValidation 参数验证注解
     * @param paramValue      参数值
     * @throws ParameterException 参数验证失败
     */
    private void validateObjectPropertiesTraditionalWay(ParameterValidation paramValidation, Object paramValue) throws ParameterException {
        Class<?> clazz = paramValue.getClass();
        Class<?>[] targetGroups = paramValidation.groups();

        // 检查是否有字段属于指定的分组（传统方式）
        if (targetGroups != null && targetGroups.length > 0) {
            boolean hasMatchingFields = false;
            for (Field field : clazz.getDeclaredFields()) {
                field.setAccessible(true);
                ParameterValidation fieldParamValidation = field.getAnnotation(ParameterValidation.class);
                if (null != fieldParamValidation) {
                    // 对于OBJECT规则，检查对象字段的分组而不是ParameterValidation注解本身的分组
                    if (isGroupMatch(fieldParamValidation.groups(), targetGroups)) {
                        hasMatchingFields = true;
                        break;
                    }
                }
            }

            // 如果没有任何字段属于指定的分组，则抛出异常
            if (!hasMatchingFields) {
                String errorMessage = "对象中没有字段属于指定的分组: " + Arrays.toString(targetGroups);
                throw new ParameterException(errorMessage);
            }
        }

        // 验证属于指定分组的字段（传统方式）
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            ParameterValidation fieldParamValidation = field.getAnnotation(ParameterValidation.class);
            if (null != fieldParamValidation) {
                // 检查分组是否匹配，不匹配则跳过
                if (targetGroups != null && targetGroups.length > 0) {
                    boolean groupMatch = isGroupMatch(fieldParamValidation.groups(), targetGroups);
                    if (!groupMatch) {
                        continue;
                    }
                }

                try {
                    Object fieldValue = field.get(paramValue);

                    if (fieldParamValidation.rules().length == 1 && fieldParamValidation.rules()[0] == ValidateRulesEnum.OBJECT) {
                        validateObjectProperties(fieldParamValidation, fieldValue);
                    } else if (Arrays.stream(fieldParamValidation.rules()).allMatch(rule -> rule == ValidateRulesEnum.OBJECT)) {
                        throw new ParameterException("参数对象验证规则设置错误!");
                    } else {
                        validateSingleValue(fieldParamValidation, fieldValue);
                    }
                } catch (IllegalAccessException e) {
                    throw new ParameterException("无法访问字段：" + field.getName() + e.getMessage());
                }
            }
        }
    }

    /**
     * 通过接口方法获取分组字段列表
     *
     * @param paramValue   参数值
     * @param targetGroups 目标分组
     * @return 分组字段名列表
     */
    private Set<String> getGroupFieldNamesFromInterface(Object paramValue, Class<?>[] targetGroups) {
        if (null == targetGroups || targetGroups.length == 0) {
            return null;
        }

        Set<String> groupFieldNames = new HashSet<>();
        for (Class<?> targetGroup : targetGroups) {
            try {
                // 直接检查参数对象是否实现了目标分组接口
                if (null != paramValue && targetGroup.isInstance(paramValue)) {
                    // 根据不同的分组类型调用对应的方法
                    if (targetGroup == Create.class && paramValue instanceof Create) {
                        Set<String> createFields = ((Create) paramValue).getCreateGroupFields();
                        if (null != createFields && !createFields.isEmpty()) {
                            groupFieldNames.addAll(createFields);
                        }
                    } else if (targetGroup == Update.class && paramValue instanceof Update) {
                        Set<String> updateFields = ((Update) paramValue).getUpdateGroupFields();
                        if (null != updateFields && !updateFields.isEmpty()) {
                            groupFieldNames.addAll(updateFields);
                        }
                    } else if (targetGroup == Query.class && paramValue instanceof Query) {
                        Set<String> queryFields = ((Query) paramValue).getQueryGroupFields();
                        if (null != queryFields && !queryFields.isEmpty()) {
                            groupFieldNames.addAll(queryFields);
                        }
                    } else if (targetGroup == StatusUpdate.class && paramValue instanceof StatusUpdate) {
                        Set<String> statusUpdateFields = ((StatusUpdate) paramValue).getStatusUpdateGroupFields();
                        if (null != statusUpdateFields && !statusUpdateFields.isEmpty()) {
                            groupFieldNames.addAll(statusUpdateFields);
                        }
                    }
                } else {
                    // 如果参数对象没有实现目标分组接口，但目标分组被指定了，应该返回一个空集合
                    // 这样可以确保使用新的分组机制而不是回退到传统机制
                    groupFieldNames.addAll(new HashSet<>());
                }
            } catch (Exception e) {
                // 如果出现异常，回退到传统方式
                log.warn("通过接口方法获取分组字段时发生异常，回退到传统方式", e);
                return null;
            }
        }

        // 如果groupFieldNames为空，说明对象实现了分组接口但没有返回任何字段，此时应该返回空集合而不是null
        // 这样可以确保使用新的分组机制而不是回退到传统机制
        return groupFieldNames;
    }

    /**
     * 验证单个参数
     *
     * @param paramValidation 注解
     * @param paramValue      参数值
     * @throws ParameterException 参数验证失败
     * @author zhou  xun
     * @since 2024-10-31
     */
    private void validateSingleValue(ParameterValidation paramValidation, Object paramValue) throws ParameterException {
        if (null == paramValidation) {
            throw new ParameterException("参数验证注解不能为空!");
        }

        for (ValidateRulesEnum rule : paramValidation.rules()) {
            switch (rule) {
                case NOT_NULL:
                    checkNull(paramValidation, paramValue);
                    break;
                case LENGTH:
                    checkLength(paramValidation, paramValue);
                    break;
                case NULL_LENGTH:
                    if (null != paramValue && !paramValue.toString().isEmpty()) {
                        checkLength(paramValidation, paramValue);
                    }
                    break;
                case DATE:
                    isValidDate(paramValidation, paramValue);
                    break;
                case TIME:
                    isValidTime(paramValidation, paramValue);
                    break;
                case DATE_TIME:
                    isValidDateTime(paramValidation, paramValue);
                    break;
                case NUMBER_MIN:
                    checkNumberMin(paramValidation, paramValue);
                    break;
                case NUMBER_MAX:
                    checkNumberMax(paramValidation, paramValue);
                    break;
                case NUMBER_RANGE:
                    checkNumberRange(paramValidation, paramValue);
                    break;
                case POSITIVE_NUMBER:
                    checkPositiveNumber(paramValidation, paramValue);
                    break;
                case NON_NEGATIVE_NUMBER:
                    checkNonNegativeNumber(paramValidation, paramValue);
                    break;
                case INTEGER:
                    checkInteger(paramValidation, paramValue);
                    break;
                case DECIMAL_SCALE:
                    checkDecimalScale(paramValidation, paramValue);
                    break;
                case ODD_NUMBER:
                    checkOddNumber(paramValidation, paramValue);
                    break;
                case EVEN_NUMBER:
                    checkEvenNumber(paramValidation, paramValue);
                    break;
                case MULTIPLE_OF:
                    checkMultipleOf(paramValidation, paramValue);
                    break;
                case NULL_DATE:
                    if (null != paramValue) {
                        isValidDate(paramValidation, paramValue);
                    }
                    break;
                case NULL_TIME:
                    if (null != paramValue) {
                        isValidTime(paramValidation, paramValue);
                    }
                    break;
                case NULL_DATE_TIME:
                    if (null != paramValue) {
                        isValidDateTime(paramValidation, paramValue);
                    }
                    break;
                case OBJECT:
                    // OBJECT规则已经在validateObjectProperties方法中处理，这里不需要额外处理
                    break;
                default:
                    throw new ParameterException("未知的验证规则: " + rule + "!");
            }
        }
    }

    /**
     * 检查参数是否在指定范围内
     *
     * @param paramValidation 注解
     * @param paramValue      参数值
     * @author zhou  xun
     * @since 2024-10-31
     */
    private void checkNumberMax(ParameterValidation paramValidation, Object paramValue) {
        if (null == paramValidation) {
            throw new ParameterException("参数验证注解不能为空!");
        }
        if (null == paramValue) {
            throw new ParameterException("验证最大值的参数" + paramValidation.desc() + "为空!");
        }
        String paramValueStr = paramValue.toString();
        if (!paramValueStr.matches("-?\\d+(\\.\\d+)?")) {
            throw new ParameterException("参数类型必须是数字类型!");
        }
        if (Double.parseDouble(paramValueStr) > paramValidation.numberMax()) {
            throw new ParameterException("参数值不能大于" + paramValidation.numberMax() + "!");
        }

    }

    /**
     * 检查参数是否在指定范围内
     *
     * @param paramValidation 注解
     * @param paramValue      参数值
     * @author zhou  xun
     * @since 2024-10-31
     */
    private void checkNumberMin(ParameterValidation paramValidation, Object paramValue) {
        if (null == paramValidation) {
            throw new ParameterException("参数验证注解不能为空!");
        }
        if (null == paramValue) {
            throw new ParameterException("验证最小值的参数" + paramValidation.desc() + "为空!");
        }
        String paramValueStr = paramValue.toString();
        if (!paramValueStr.matches("-?\\d+(\\.\\d+)?")) {
            throw new ParameterException("参数类型必须是数字类型!");
        }
        if (Double.parseDouble(paramValueStr) < paramValidation.numberMin()) {
            throw new ParameterException("参数值不能小于" + paramValidation.numberMin() + "!");
        }
    }

    /**
     * 检查参数是否在指定的数值范围内
     *
     * @param paramValidation 注解
     * @param paramValue      参数值
     */
    private void checkNumberRange(ParameterValidation paramValidation, Object paramValue) {
        if (null == paramValidation) {
            throw new ParameterException("参数验证注解不能为空!");
        }
        if (null == paramValue) {
            throw new ParameterException("验证范围的参数" + paramValidation.desc() + "为空!");
        }
        String paramValueStr = paramValue.toString();
        if (!paramValueStr.matches("-?\\d+(\\.\\d+)?")) {
            throw new ParameterException("参数类型必须是数字类型!");
        }

        double value = Double.parseDouble(paramValueStr);
        if (value < paramValidation.numberMin() || value > paramValidation.numberMax()) {
            throw new ParameterException("参数值必须在" + paramValidation.numberMin() + "到" + paramValidation.numberMax() + "之间!");
        }
    }

    /**
     * 检查参数是否为正数
     *
     * @param paramValidation 注解
     * @param paramValue      参数值
     */
    private void checkPositiveNumber(ParameterValidation paramValidation, Object paramValue) {
        if (null == paramValidation) {
            throw new ParameterException("参数验证注解不能为空!");
        }
        if (null == paramValue) {
            throw new ParameterException("验证正数的参数" + paramValidation.desc() + "为空!");
        }
        String paramValueStr = paramValue.toString();
        if (!paramValueStr.matches("-?\\d+(\\.\\d+)?")) {
            throw new ParameterException("参数类型必须是数字类型!");
        }

        double value = Double.parseDouble(paramValueStr);
        if (value <= 0) {
            throw new ParameterException("参数值必须是正数!");
        }
    }

    /**
     * 检查参数是否为非负数
     *
     * @param paramValidation 注解
     * @param paramValue      参数值
     */
    private void checkNonNegativeNumber(ParameterValidation paramValidation, Object paramValue) {
        if (null == paramValidation) {
            throw new ParameterException("参数验证注解不能为空!");
        }
        if (null == paramValue) {
            throw new ParameterException("验证非负数的参数" + paramValidation.desc() + "为空!");
        }
        String paramValueStr = paramValue.toString();
        if (!paramValueStr.matches("-?\\d+(\\.\\d+)?")) {
            throw new ParameterException("参数类型必须是数字类型!");
        }

        double value = Double.parseDouble(paramValueStr);
        if (value < 0) {
            throw new ParameterException("参数值不能为负数!");
        }
    }

    /**
     * 检查参数是否为整数
     *
     * @param paramValidation 注解
     * @param paramValue      参数值
     */
    private void checkInteger(ParameterValidation paramValidation, Object paramValue) {
        if (null == paramValidation) {
            throw new ParameterException("参数验证注解不能为空!");
        }
        if (null == paramValue) {
            throw new ParameterException("验证整数的参数" + paramValidation.desc() + "为空!");
        }
        String paramValueStr = paramValue.toString();
        if (!paramValueStr.matches("-?\\d+")) {
            throw new ParameterException("参数值必须是整数!");
        }
    }

    /**
     * 检查参数的小数位数是否符合要求
     *
     * @param paramValidation 注解
     * @param paramValue      参数值
     */
    private void checkDecimalScale(ParameterValidation paramValidation, Object paramValue) {
        if (null == paramValidation) {
            throw new ParameterException("参数验证注解不能为空!");
        }
        if (null == paramValue) {
            throw new ParameterException("验证小数位数的参数" + paramValidation.desc() + "为空!");
        }
        String paramValueStr = paramValue.toString();
        if (!paramValueStr.matches("-?\\d+(\\.\\d+)?")) {
            throw new ParameterException("参数类型必须是数字类型!");
        }

        try {
            BigDecimal decimal = new BigDecimal(paramValueStr);
            int scale = decimal.scale();
            if (scale > paramValidation.scale()) {
                throw new ParameterException("参数值的小数位数不能超过" + paramValidation.scale() + "位!");
            }
        } catch (NumberFormatException e) {
            throw new ParameterException("参数值必须是有效的数字!");
        }
    }

    /**
     * 检查参数是否为奇数
     *
     * @param paramValidation 注解
     * @param paramValue      参数值
     */
    private void checkOddNumber(ParameterValidation paramValidation, Object paramValue) {
        if (null == paramValidation) {
            throw new ParameterException("参数验证注解不能为空!");
        }
        if (null == paramValue) {
            throw new ParameterException("验证奇数的参数" + paramValidation.desc() + "为空!");
        }
        String paramValueStr = paramValue.toString();
        if (!paramValueStr.matches("-?\\d+")) {
            throw new ParameterException("参数类型必须是整数类型!");
        }

        long value = Long.parseLong(paramValueStr);
        if (value % 2 == 0) {
            throw new ParameterException("参数值必须是奇数!");
        }
    }

    /**
     * 检查参数是否为偶数
     *
     * @param paramValidation 注解
     * @param paramValue      参数值
     */
    private void checkEvenNumber(ParameterValidation paramValidation, Object paramValue) {
        if (null == paramValidation) {
            throw new ParameterException("参数验证注解不能为空!");
        }
        if (null == paramValue) {
            throw new ParameterException("验证偶数的参数" + paramValidation.desc() + "为空!");
        }
        String paramValueStr = paramValue.toString();
        if (!paramValueStr.matches("-?\\d+")) {
            throw new ParameterException("参数类型必须是整数类型!");
        }

        long value = Long.parseLong(paramValueStr);
        if (value % 2 != 0) {
            throw new ParameterException("参数值必须是偶数!");
        }
    }

    /**
     * 检查参数是否为指定数字的倍数
     *
     * @param paramValidation 注解
     * @param paramValue      参数值
     */
    private void checkMultipleOf(ParameterValidation paramValidation, Object paramValue) {
        if (null == paramValidation) {
            throw new ParameterException("参数验证注解不能为空!");
        }
        if (null == paramValue) {
            throw new ParameterException("验证倍数的参数" + paramValidation.desc() + "为空!");
        }
        String paramValueStr = paramValue.toString();
        if (!paramValueStr.matches("-?\\d+")) {
            throw new ParameterException("参数类型必须是整数类型!");
        }

        long value = Long.parseLong(paramValueStr);
        if (paramValidation.multipleOf() == 0) {
            throw new ParameterException("倍数不能为0!");
        }

        if (value % paramValidation.multipleOf() != 0) {
            throw new ParameterException("参数值必须是" + paramValidation.multipleOf() + "的倍数!");
        }
    }

    private void checkNull(ParameterValidation paramValidation, Object paramValue) {
        // 检查参数是否为 null
        if (null == paramValue) {
            throw new ParameterException(paramValidation.desc() + "不能为空!");
        }
        // 去除首尾空白字符
        String paramValueStr = paramValue.toString().trim();
        // 检查字符串是否为空、"null" 或 "undefined"
        if (paramValueStr.isEmpty() || "null".equals(paramValueStr) || "undefined".equals(paramValueStr)) {
            throw new ParameterException(paramValidation.desc() + "不能为空!");
        }
    }

    /**
     * 检查参数值的长度是否在指定的范围内。
     *
     * @param paramValidation 参数验证注解
     * @param paramValue      参数值
     * @throws ParameterException 如果长度不在指定范围内
     */
    private void checkLength(ParameterValidation paramValidation, Object paramValue) {
        if (null == paramValidation) {
            throw new ParameterException("参数验证注解不能为空!");
        }

        String length = paramValidation.length();
        if (null == paramValue) {
            throw new ParameterException("验证长度的参数" + paramValidation.desc() + "为空!");
        }
        if (null == length || length.isEmpty()) {
            throw new ParameterException("长度未设置!");
        }

        String paramStr = paramValue.toString();
        int paramLength = paramStr.length();

        //判断设置的是否是单个值,如果是,直接处理
        if (length.matches("\\d+")) {
            int targetLength = Integer.parseInt(length);
            if (paramLength != targetLength) {
                throw new ParameterException("参数长度不符合要求: " + paramValidation.desc() + "长度必须是" + targetLength + "!");
            }
        } else {
            if (!length.contains("~")) {
                throw new ParameterException("长度区间使用“~”连接!");
            }
            String[] splitLength = length.split("~");

            if (splitLength.length != 2 || !splitLength[0].matches("\\d+") || !splitLength[1].matches("\\d+")) {
                throw new ParameterException("长度区间设置错误,最小长度和最大长度应设置为整数!");
            }

            int minLength = Integer.parseInt(splitLength[0]);
            int maxLength = Integer.parseInt(splitLength[1]);

            if (minLength > maxLength) {
                throw new ParameterException("长度区间设置错误,最小长度不能大于最大长度!");
            }

            if (paramLength < minLength || paramLength > maxLength) {
                throw new ParameterException("参数长度不符合要求: " + paramValidation.desc() + "长度必须在" + minLength + "~" + maxLength + "之间!");
            }
        }
    }

    /**
     * 检查参数值是否符合指定的日期格式。
     *
     * @param paramValidation 参数验证注解
     * @param paramValue      参数值
     * @throws ParameterException 如果参数值不符合日期格式
     */
    private void isValidDate(ParameterValidation paramValidation, Object paramValue) {
        if (null == paramValidation) {
            throw new ParameterException("参数验证注解不能为空!");
        }

        DateTimeFormatter formatter = getFormatterOrDefault(paramValidation.dateFormat());
        if (null == paramValue) {
            throw new ParameterException("验证的日期参数" + paramValidation.desc() + "为空!");
        }
        try {
            // 如果参数值已经是LocalDate类型，则不需要再解析
            if (paramValue instanceof LocalDate) {
                return;
            }
            LocalDate.parse(paramValue.toString(), formatter);
        } catch (DateTimeParseException e) {
            throw new ParameterException(paramValidation.desc() + "格式不正确!");
        }
    }

    /**
     * 检查参数值是否符合指定的时间格式。
     *
     * @param paramValidation 参数验证注解
     * @param paramValue      参数值
     * @throws ParameterException 如果参数值不符合时间格式
     */
    private void isValidTime(ParameterValidation paramValidation, Object paramValue) {
        if (null == paramValidation) {
            throw new ParameterException("参数验证注解不能为空!");
        }

        DateTimeFormatter formatter = getFormatterOrDefault(paramValidation.dateFormat());
        if (null == paramValue) {
            throw new ParameterException("验证的时间参数" + paramValidation.desc() + "为空!");
        }
        try {
            // 如果参数值已经是LocalTime类型，则不需要再解析
            if (paramValue instanceof LocalTime) {
                return;
            }
            LocalTime.parse(paramValue.toString(), formatter);
        } catch (DateTimeParseException e) {
            throw new ParameterException(paramValidation.desc() + "格式不正确!");
        }
    }

    /**
     * 检查参数值是否符合指定的日期时间格式。
     *
     * @param paramValidation 参数验证注解
     * @param paramValue      参数值
     * @throws ParameterException 如果参数值不符合日期时间格式
     */
    private void isValidDateTime(ParameterValidation paramValidation, Object paramValue) {
        if (null == paramValidation) {
            throw new ParameterException("参数验证注解不能为空!");
        }

        DateTimeFormatter formatter = getFormatterOrDefault(paramValidation.dateFormat());
        if (null == paramValue) {
            throw new ParameterException("验证的日期时间参数" + paramValidation.desc() + "为空!");
        }
        try {
            // 如果参数值已经是LocalDateTime类型，则不需要再解析
            if (paramValue instanceof LocalDateTime) {
                return;
            }
            // 对于中文格式，需要使用特定的解析方式
            if (paramValidation.dateFormat() == DateTimeFormatEnum.CHINESE) {
                LocalDateTime.parse(paramValue.toString(), formatter.withLocale(java.util.Locale.CHINESE));
            } else {
                LocalDateTime.parse(paramValue.toString(), formatter);
            }
        } catch (DateTimeParseException e) {
            throw new ParameterException(paramValidation.desc() + "格式不正确!");
        }
    }

    /**
     * 获取日期时间格式化器。如果提供了自定义格式，则使用自定义格式；否则抛出异常。
     *
     * @param format 自定义格式字符串
     * @return 日期时间格式化器
     * @throws ParameterException 如果日期、时间格式未设置
     */
    private DateTimeFormatter getFormatterOrDefault(DateTimeFormatEnum format) {
        if (null == format || format == DateTimeFormatEnum.NULL) {
            throw new ParameterException("日期、时间格式未设置!");
        }
        // 对于中文格式，需要指定中文Locale
        if (format == DateTimeFormatEnum.CHINESE) {
            return DateTimeFormatter.ofPattern(format.getPattern(), java.util.Locale.CHINESE);
        }
        return DateTimeFormatter.ofPattern(format.getPattern());
    }
}